home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / ProcDoggie 1.0a6 / UMenuHandler.inc1.p < prev    next >
Encoding:
Text File  |  1991-02-07  |  10.8 KB  |  346 lines  |  [TEXT/MPS ]

  1. {-------------------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    Code to handle events in menus
  6. #
  7. #    Program:    ProcDoggie
  8. #    File:        UMenuHandler.inc1.p - Pascal Implementation
  9. #
  10. #    by:        Forrest Tanaka
  11. #
  12. #    Copyright © 1988-1991 Apple Computer, Inc.
  13. #    All rights reserved.
  14. #
  15. -------------------------------------------------------------------------------}
  16. {[j=20/57/1$] Pasmat Options}
  17. {$R-}
  18.  
  19.  
  20. (*******************************************************************************
  21. * Constants
  22. *******************************************************************************)
  23.  
  24.     CONST
  25.         rMenuBar = 128; {Resource ID of this application’s MBAR resource}
  26.  
  27.         mFirst = mFile;    {Menu ID of the first non-Apple menu in the menu list}
  28.         mLast  = mProcess; {Menu ID of the last menu in the menu list}
  29.  
  30.  
  31. (*******************************************************************************
  32. * Types
  33. *******************************************************************************)
  34.  
  35.     TYPE
  36.         MenuGuide = RECORD
  37.             theMenu: MenuHandle; {Handle to this guide’s menu}
  38.             enables: LongInt     {Current enable flags}
  39.         END;
  40.  
  41.  
  42. (*******************************************************************************
  43. * Variables
  44. *******************************************************************************)
  45.  
  46.     VAR
  47.         gMenuGuides: ARRAY [mFirst..mLast] OF MenuGuide;
  48.  
  49.  
  50. {$S %A5Init}
  51. (*******************************************************************************
  52. * Public: DoAppleMenu
  53. *
  54. * The menu guide array is initialized with the menu handles and enable flags of
  55. * all menus.
  56. *
  57. * If GetNewMBar couldn’t load the MBAR resource, then it returns NIL and the
  58. * error code is in ResError, and I can deal with the error elegantly.  But, if
  59. * the GetNewMBar couldn’t load the menus themselves, then it’ll probably crash.
  60. *******************************************************************************)
  61.  
  62.     PROCEDURE StartMenus;
  63.  
  64.         VAR
  65.             menuBar:   Handle;  {Handle to the menu bar from the MBAR resource}
  66.             menuIndex: Integer; {Index into menu guide records}
  67.  
  68.     BEGIN
  69.         (* Load in the menu bar *)
  70.         menuBar := GetNewMBar (rMenuBar);
  71.         IF menuBar <> NIL THEN
  72.             BEGIN
  73.                 (* Set it, then dispose of it because SetMenuBar makes a copy *)
  74.                 SetMenuBar (menuBar);
  75.                 DisposHandle (menuBar);
  76.  
  77.                 (* Add the desk accessories to the Apple menu *)
  78.                 AddResMenu (GetMHandle (mApple), 'DRVR');
  79.  
  80.                 (* Initialize the menu guide array *)
  81.                 FOR menuIndex := mFile TO mProcess DO
  82.                     BEGIN
  83.                         gMenuGuides [menuIndex].theMenu := GetMHandle (menuIndex);
  84.                         gMenuGuides [menuIndex].enables := gMenuGuides [menuIndex].
  85.                                 theMenu^^.enableFlags
  86.                     END;
  87.  
  88.                 (* Draw the menu bar *)
  89.                 DrawMenuBar
  90.             END
  91.         ELSE
  92.             IF ResError = memFullErr THEN
  93.                 gError := memFullErr
  94.             ELSE IF (ResError = noErr) OR (ResError = resNotFound) THEN
  95.                 gError := resNotFound
  96.             ELSE
  97.                 gError := dsSysErr
  98.     END;
  99.  
  100.  
  101. {$S Main}
  102. (*******************************************************************************
  103. * Private: DoAppleMenu - Handle an Apple menu item choice
  104. *
  105. * This routine is called whenever it’s determined that the chosen menu item was
  106. * in the Apple menu.  If the chosen menu item that’s passed in the menuItem
  107. * parameter wasn’t the About item, the name of the menu item is retrieved and
  108. * then OpenDeskAcc is called with this name so that the desk accessory by that
  109. * name is opened.  The Process Manager can launch desk accessories, but
  110. * OpenDeskAcc should still be used if the user chooses any item in the Apple
  111. * menu.
  112. *******************************************************************************)
  113.  
  114.     PROCEDURE DoAppleMenu (menuItem: Integer);
  115.  
  116.         VAR
  117.             daName: Str255;  {Name of the chosen DA}
  118.             refNum: Integer; {Reference number of the DA, ignored}
  119.  
  120.     BEGIN
  121.         IF menuItem = iAbout THEN
  122.             ShowAboutBox
  123.         ELSE
  124.             BEGIN
  125.                 GetItem (GetMHandle (mApple), menuItem, (*<*)daName);
  126.                 refNum := OpenDeskAcc (daName)
  127.             END
  128.     END;
  129.  
  130.  
  131. {$S Main}
  132. (*******************************************************************************
  133. * Private: DoFileMenu - Handle a File menu item choice
  134. *
  135. * This routine is called whenever it’s determined that the chosen menu item was
  136. * in the File menu.  The item number of the chosen menu item is passed in the
  137. * menuItem parameter.
  138. *******************************************************************************)
  139.  
  140.     PROCEDURE DoFileMenu (menuItem: Integer);
  141.  
  142.     BEGIN
  143.         CASE menuItem OF
  144.             iLaunchFore:
  145.                 DoLaunchInFront;
  146.             iLaunchBack:
  147.                 DoLaunchInBack;
  148.             iLaunchTo:
  149.                 DoLaunchTo;
  150.             iJustLaunch,
  151.             iOpenLaunch,
  152.             iPrintLaunch:
  153.                 DoLaunchMode (menuItem);
  154.             iQuit:
  155.                 DoQuit
  156.         END
  157.     END;
  158.  
  159.  
  160. {$S Main}
  161. (*******************************************************************************
  162. * Private: DoProcessMenu - Handle a Process menu item choice
  163. *
  164. * This routine is called whenever it’s determined that the chosen menu item was
  165. * in the Process menu.  The item number of the chosen menu item is passed in the
  166. * menuItem parameter.
  167. *******************************************************************************)
  168.  
  169.     PROCEDURE DoProcessMenu (menuItem: Integer);
  170.  
  171.     BEGIN
  172.         CASE menuItem OF
  173.             iBringFront:
  174.                 DoBringProcessToFront (FrontWindow);
  175.             iShowProcessInfo:
  176.                 DoGetProcessInfo (FrontWindow);
  177.             iTerminateProcess:
  178.                 DoTerminateProcess (FrontWindow)
  179.         END
  180.     END;
  181.  
  182.  
  183. {$S Main}
  184. (*******************************************************************************
  185. * Public: DoMenuChoice
  186. *
  187. * This routine should be self-explanatory.
  188. *******************************************************************************)
  189.  
  190.     PROCEDURE DoMenuChoice (menuChoice: LongInt);
  191.  
  192.         VAR
  193.             menuNum:  Integer; {Menu number of chosen menu}
  194.             menuItem: Integer; {Item number of chosen menu item}
  195.  
  196.     BEGIN
  197.         IF menuChoice <> 0 THEN
  198.             BEGIN
  199.                 (* Get the chosen menu item and menu number *)
  200.                 menuNum := HiWord (menuChoice);
  201.                 menuItem := LoWord (menuChoice);
  202.  
  203.                 (* Dispatch the appropriate menu-handling routine *)
  204.                 CASE menuNum OF
  205.                     mApple:
  206.                         DoAppleMenu (menuItem);
  207.                     mFile:
  208.                         DoFileMenu (menuItem);
  209.                     mProcess:
  210.                         DoProcessMenu (menuItem);
  211.                 END;
  212.                 HiliteMenu (0)
  213.             END
  214.     END;
  215.  
  216.  
  217. {$S Main}
  218. (*******************************************************************************
  219. * Private: ResetMenuItems - Disable any disableable items and clear marks
  220. *
  221. * Disabling all the menu items is done bruteforcedly.  It could easily be done
  222. * by looping through each menu and disabling every item that comes up (disabling
  223. * the Font menu is done this way), but I thought doing it using the brute-force
  224. * method was clearer.  Then again. . .
  225. *******************************************************************************)
  226.  
  227.     PROCEDURE ResetMenuItems;
  228.  
  229.         VAR
  230.             aMenu: MenuHandle; {Handle to each menu we’re disabling}
  231.  
  232.     BEGIN
  233.         (* Disable items in the File menu *)
  234.         aMenu := GetMHandle (mFile);
  235.         DisableItem (aMenu, iLaunchFore);
  236.         DisableItem (aMenu, iLaunchBack);
  237.         DisableItem (aMenu, iLaunchTo);
  238.         SetItemMark (aMenu, iJustLaunch, CHR (noMark));
  239.         SetItemMark (aMenu, iOpenLaunch, CHR (noMark));
  240.         SetItemMark (aMenu, iPrintLaunch, CHR (noMark));
  241.  
  242.         (* Disable items in the Process menu *)
  243.         aMenu := GetMHandle (mProcess);
  244.         DisableItem (aMenu, iBringFront);
  245.         DisableItem (aMenu, iShowProcessInfo);
  246.         DisableItem (aMenu, iTerminateProcess);
  247.     END;
  248.  
  249.  
  250. {$S Main}
  251. (*******************************************************************************
  252. * Public: FixMenus
  253. *
  254. * FixMenus first disables every available menu item.  Then the most basic menu
  255. * items are enabled.  The windowKind field of the front window is then checked.
  256. * If there is a window open, FixMenus calls a routine that’s responsible for
  257. * that kind of window to enable any menu items that are relevant to that kind of
  258. * window.
  259. *
  260. * If the front window is a modal dialog, then the basic set of menu items are
  261. * NOT enabled, and the entire Apple menu is disabled.
  262. *
  263. * After this is done, the menu bar might have to be redrawn to reflect the new
  264. * conditions.  So, FixMenus go through every menu to determine if the state of
  265. * the entire menu has changed.  The MenuGuide records are used to help determine
  266. * this.  If the state of any many has changed, then the menu bar is redrawn.
  267. *******************************************************************************)
  268.  
  269.     PROCEDURE FixMenus;
  270.  
  271.         VAR
  272.             currWindow: WindowPtr;  {Pointer to the front-most window}
  273.             currMenu:   MenuHandle; {Handle to menu being enabled}
  274.             oldEnables: LongInt;    {True if 1+ menu items enabled when FixMenus called}
  275.             newEnables: LongInt;    {True if 1+ menu items enabled after menus fixed}
  276.             mustRedraw: Boolean;    {TRUE if menu bar has to be redrawn}
  277.             numItems:   Integer;    {Number of items in a menu}
  278.             menuIndex:  Integer;    {Index into menu guide array}
  279.  
  280.     BEGIN
  281.         (* Start by disabling all menus *)
  282.         ResetMenuItems;
  283.  
  284.         (* Front-most window determines most menu enabling/disabling *)
  285.         currWindow := FrontWindow;
  286.  
  287.         (* Fix the marks for the launch mode items *)
  288.         currMenu := GetMHandle (mFile);
  289.         CASE GetLaunchMode OF
  290.             kJustLaunch:
  291.                 CheckItem (currMenu, iJustLaunch, TRUE);
  292.             kOpenLaunch:
  293.                 CheckItem (currMenu, iOpenLaunch, TRUE);
  294.             kPrintLaunch:
  295.                 CheckItem (currMenu, iPrintLaunch, TRUE)
  296.         END;
  297.  
  298.         (* Enable any window-specific menu items *)
  299.         IF currWindow <> NIL THEN
  300.             IF IsProcessListWindow (currWindow) THEN
  301.                 (* Process list window in front, set up menu items in it *)
  302.                 FixProcessListMenus (currWindow)
  303.             ELSE IF IsProcessInfoWindow (currWindow) THEN
  304.                 (* Process info window in front, set up menu items in it *)
  305.                 FixProcessInfoMenus (currWindow);
  306.  
  307.         (* Assume we don’t have to redraw the menu bar *)
  308.         mustRedraw := FALSE;
  309.  
  310.         (* Check through every menu to see if there are any enabled items in it *)
  311.         FOR menuIndex := mFirst TO mLast DO
  312.             BEGIN
  313.                 (* Grab the old and new enable flags excluding the flag for the entire menu *)
  314.                 oldEnables := BAnd (gMenuGuides [menuIndex].enables, $FFFFFFFE);
  315.                 newEnables := BAnd (gMenuGuides [menuIndex].theMenu^^.enableFlags,
  316.                         $FFFFFFFE);
  317.  
  318.                 (* Shift left so that we only see flags for existing items *)
  319.                 numItems := CountMItems (gMenuGuides [menuIndex].theMenu);
  320.                 oldEnables := BitShift (oldEnables, 31 - numItems);
  321.                 newEnables := BitShift (newEnables, 31 - numItems);
  322.  
  323.                 (* Determine if the menu bar must be redrawn *)
  324.                 IF (oldEnables <> 0) AND (newEnables = 0) THEN
  325.                     BEGIN
  326.                         (* Had some items enabled, now has no items enabled, redraw *)
  327.                         DisableItem (gMenuGuides [menuIndex].theMenu, 0);
  328.                         mustRedraw := TRUE
  329.                     END
  330.                 ELSE IF (oldEnables = 0) AND (newEnables <> 0) THEN
  331.                     BEGIN
  332.                         (* Had no items enabled, now has some items enabled, redraw *)
  333.                         EnableItem (gMenuGuides [menuIndex].theMenu, 0);
  334.                         mustRedraw := TRUE
  335.                     END;
  336.  
  337.                 (* Update our copy of the enable flags *)
  338.                 gMenuGuides [menuIndex].enables := gMenuGuides [menuIndex].
  339.                         theMenu^^.enableFlags
  340.             END;
  341.  
  342.         (* If at least one menu has changed state, must redraw the menu bar *)
  343.         IF mustRedraw THEN
  344.             InvalMenuBar
  345.     END;
  346.